/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pop3;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author epulapp
 */
public class ClientPOP {

    private int etat; //0 = non connecté   1 = connecté
    private Socket s;
    private OutputStream ops;
    private BufferedWriter bufo;
    private BufferedReader bufi;
    
    private String message;
    private int essai = 0;
    
    /*public ClientPOP(){
        
    }*/

    public boolean connect(String adresse) {
        try {
            
            this.s = new Socket(InetAddress.getByName(adresse), 110);
            
            this.s.setSoLinger(true, 10000);
            this.etat = 0;
            
            this.bufo = new BufferedWriter(new OutputStreamWriter(this.s.getOutputStream()));
            this.bufi = new BufferedReader(new InputStreamReader(this.s.getInputStream()));
            receptionReponse();
            
            System.out.println(this.message);
            if(this.message.startsWith("+OK")){
                this.essai = 0;
                return true;
            }else {
                this.s.close();
                return false;
                /*if(this.essai > 3){
                    this.s.close();
                    this.essai = 0;
                    System.err.println("échec de connexion");
                }else{
                    System.out.println("tentative de reconnexion "+ this.essai);
                    this.essai++;
                    this.s.close();
                    connect(adresse);
                }*/
            }
            
        } catch (IOException ioe) {
            System.err.println(ioe.getMessage());
            return false;
        } 
    }
    
    public boolean isConnect(){
        return !this.s.isClosed();
    }

    //commande APOP
    public String connexion(String login, String pwd) {
        try {
            if (verifConnexion(0)) {
                String commande = "APOP " + login + " " + pwd + "\r\n";

                envoiCommande(commande);
                this.etat = 1;
                
                receptionReponse();
                System.out.println(this.message);
                return this.message;
                
            }else{
                 System.err.println("Vous êtes déjà connecté, vous ne pouvez vous reconnecter");
                 return "Vous êtes déjà connecté, vous ne pouvez vous reconnecter";
            }
        } catch (Exception ioe) {
            System.err.println(ioe.getMessage());
            return "Erreur survenue lors de la connexion";
        }
    }

    //commande RETR numMsg
    public String recuperation(int numMsg) {
        FileWriter fw = null;
        String message = null;
        try {
            if (verifConnexion(1)) {
                String commande = "RETR " + numMsg + "\r\n";

                envoiCommande(commande);
                this.etat = 1;
                
                receptionReponse();
                if (this.message.startsWith("+OK")) {
                    MessageHandler mh = new MessageHandler();
                    File file = new File("messageClient"+numMsg+".txt");
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    fw = new FileWriter(file);
                    
                    String mess = mh.readMessage(bufi);
                    
                    fw.write(mess);
                    fw.flush();
                }
                System.out.println(this.message);
                message = this.message;
                
            }else {
                System.err.println("Vous ne pouvez récupérer votre message sans connexion");
                message = "Vous ne pouvez récupérer votre message sans connexion";
            }
        } catch (Exception ioe) {
            System.err.println(ioe.getMessage());
            message = "Erreur lors de la récupération de votre message";
        } finally {
            try {
                fw.close();
            } catch (Exception e) {}
            return message;
        }
    }

    //commande STAT
    public String statutCourrier() {
        try {
            if (verifConnexion(1)) {
                String commande = "STAT\r\n";

                envoiCommande(commande);
                this.etat = 1;
                
                receptionReponse();
                System.out.println(this.message);
                return this.message;
            }else {
                System.err.println("Vous ne pouvez consulter votre messagerie sans connexion");
                return "Vous ne pouvez consulter votre messagerie sans connexion";
            }
        } catch (Exception ioe) {
            System.err.println(ioe.getMessage());
            return "Erreur lors de la consultation de votre messagerie";
        }
    }

    //commande QUIT
    public String deconnexion() {
        try {
            envoiCommande("QUIT\r\n");
            this.etat = 0;

            receptionReponse(); 
            System.out.println(this.message); 

            if(this.message.startsWith("+OK")){                
                System.out.println("Deconnexion reussie sans probleme");
            } else if(this.message.startsWith("-ERR")){
                System.out.println("Deconnexion reussie avec probleme");
            }
            
        } catch (Exception e) {
            System.err.println(e.getMessage());
            this.message += "\n Erreur lors de la déconnexion";
                    
        } finally {
            try {
                this.bufi.close();
                this.bufo.close();
                this.s.close();
                this.message += "\n Socket fermée";
            } catch (Exception e) {}
            finally{
                return this.message;
            }
        }
    }

    public void envoiCommande(String toSend) {
        try {
            this.bufo.write(toSend);
            this.bufo.flush();
        } catch (IOException ioe) {
            System.err.println(ioe.getMessage());
        }

    }

    private boolean verifConnexion(int i) {
        if (etat != i) {
            System.err.println("Action non possible, etat incorrecte : " + i);
            return false;
        } else {
            return true;
        }
    }

    private void receptionReponse() {
        try {
            this.message = "";
            message += this.bufi.readLine();

        } catch (Exception ex) {
            System.err.println(ex.getMessage());
        }
    }
    
    public static void main(String[] args) {
        ClientPOP clipop = new ClientPOP();
        if (clipop.connect("127.0.0.1")) {
            clipop.connexion("toto", "bidule");
            clipop.statutCourrier();
            clipop.recuperation(1);
            clipop.recuperation(2);
            clipop.recuperation(3);
            clipop.deconnexion();

            System.out.println("Socket ouvert : " + clipop.isConnect());
        }   
    }
}
